<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

/**
 * Think 系统函数库
 */

/**
 * 获取和设置配置参数 支持批量定义
 *
 * @param string|array $name
 *        	配置变量
 * @param mixed $value
 *        	配置值
 * @param mixed $default
 *        	默认值
 * @return mixed
 */
function C($name = null, $value = null, $default = null) {
	static $_config = array ();
	// 无参数时获取所有
	if (empty ( $name )) {
		return $_config;
	}
	// 优先执行设置获取或赋值
	if (is_string ( $name )) {
		if (! strpos ( $name, '.' )) {
			$name = strtoupper ( $name );
			if (is_null ( $value ))
				return isset ( $_config [$name] ) ? $_config [$name] : $default;
			$_config [$name] = $value;
			return null;
		}
		// 二维数组设置和获取支持
		$name = explode ( '.', $name );
		$name [0] = strtoupper ( $name [0] );
		if (is_null ( $value ))
			return isset ( $_config [$name [0]] [$name [1]] ) ? $_config [$name [0]] [$name [1]] : $default;
		$_config [$name [0]] [$name [1]] = $value;
		return null;
	}
	// 批量设置
	if (is_array ( $name )) {
		$_config = array_merge ( $_config, array_change_key_case ( $name, CASE_UPPER ) );
		return null;
	}
	return null; // 避免非法参数
}

/**
 * 加载配置文件 支持格式转换 仅支持一级配置
 *
 * @param string $file
 *        	配置文件名
 * @param string $parse
 *        	配置解析方法 有些格式需要用户自己解析
 * @return array
 */
function load_config($file, $parse = CONF_PARSE) {
	$ext = pathinfo ( $file, PATHINFO_EXTENSION );
	switch ($ext) {
		case 'php' :
			return include $file;
		case 'ini' :
			return parse_ini_file ( $file );
		case 'yaml' :
			return yaml_parse_file ( $file );
		case 'xml' :
			return ( array ) simplexml_load_file ( $file );
		case 'json' :
			return json_decode ( file_get_contents ( $file ), true );
		default :
			if (function_exists ( $parse )) {
				return $parse ( $file );
			} else {
				E ( L ( '_NOT_SUPPORT_' ) . ':' . $ext );
			}
	}
}

/**
 * 解析yaml文件返回一个数组
 *
 * @param string $file
 *        	配置文件名
 * @return array
 */
if (! function_exists ( 'yaml_parse_file' )) {
	function yaml_parse_file($file) {
		vendor ( 'spyc.Spyc' );
		return Spyc::YAMLLoad ( $file );
	}
}

/**
 * 抛出异常处理
 *
 * @param string $msg
 *        	异常消息
 * @param integer $code
 *        	异常代码 默认为0
 * @throws Think\Exception
 * @return void
 */
function E($msg, $code = 0) {
	throw new Think\Exception ( $msg, $code );
}

/**
 * 记录和统计时间（微秒）和内存使用情况
 * 使用方法:
 * <code>
 * G('begin'); // 记录开始标记位
 * // ... 区间运行代码
 * G('end'); // 记录结束标签位
 * echo G('begin','end',6); // 统计区间运行时间 精确到小数后6位
 * echo G('begin','end','m'); // 统计区间内存使用情况
 * 如果end标记位没有定义，则会自动以当前作为标记位
 * 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效
 * </code>
 *
 * @param string $start
 *        	开始标签
 * @param string $end
 *        	结束标签
 * @param integer|string $dec
 *        	小数位或者m
 * @return mixed
 */
function G($start, $end = '', $dec = 4) {
	static $_info = array ();
	static $_mem = array ();
	if (is_float ( $end )) { // 记录时间
		$_info [$start] = $end;
	} elseif (! empty ( $end )) { // 统计时间和内存使用
		if (! isset ( $_info [$end] ))
			$_info [$end] = microtime ( TRUE );
		if (MEMORY_LIMIT_ON && $dec == 'm') {
			if (! isset ( $_mem [$end] ))
				$_mem [$end] = memory_get_usage ();
			return number_format ( ($_mem [$end] - $_mem [$start]) / 1024 );
		} else {
			return number_format ( ($_info [$end] - $_info [$start]), $dec );
		}
	} else { // 记录时间和内存使用
		$_info [$start] = microtime ( TRUE );
		if (MEMORY_LIMIT_ON)
			$_mem [$start] = memory_get_usage ();
	}
	return null;
}

/**
 * 获取和设置语言定义(不区分大小写)
 *
 * @param string|array $name
 *        	语言变量
 * @param mixed $value
 *        	语言值或者变量
 * @return mixed
 */
function L($name = null, $value = null) {
	static $_lang = array ();
	// 空参数返回所有定义
	if (empty ( $name ))
		return $_lang;
	// 判断语言获取(或设置)
	// 若不存在,直接返回全大写$name
	if (is_string ( $name )) {
		$name = strtoupper ( $name );
		if (is_null ( $value )) {
			return isset ( $_lang [$name] ) ? $_lang [$name] : $name;
		} elseif (is_array ( $value )) {
			// 支持变量
			$replace = array_keys ( $value );
			foreach ( $replace as &$v ) {
				$v = '{$' . $v . '}';
			}
			return str_replace ( $replace, $value, isset ( $_lang [$name] ) ? $_lang [$name] : $name );
		}
		$_lang [$name] = $value; // 语言定义
		return null;
	}
	// 批量定义
	if (is_array ( $name ))
		$_lang = array_merge ( $_lang, array_change_key_case ( $name, CASE_UPPER ) );
	return null;
}

/**
 * 添加和获取页面Trace记录
 *
 * @param string $value
 *        	变量
 * @param string $label
 *        	标签
 * @param string $level
 *        	日志级别
 * @param boolean $record
 *        	是否记录日志
 * @return void|array
 */
function trace($value = '[think]', $label = '', $level = 'DEBUG', $record = false) {
	return Think\Think::trace ( $value, $label, $level, $record );
}

/**
 * 编译文件
 *
 * @param string $filename
 *        	文件名
 * @return string
 */
function compile($filename) {
	$content = php_strip_whitespace ( $filename );
	$content = trim ( substr ( $content, 5 ) );
	// 替换预编译指令
	$content = preg_replace ( '/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content );
	if (0 === strpos ( $content, 'namespace' )) {
		$content = preg_replace ( '/namespace\s(.*?);/', 'namespace \\1{', $content, 1 );
	} else {
		$content = 'namespace {' . $content;
	}
	if ('?>' == substr ( $content, - 2 ))
		$content = substr ( $content, 0, - 2 );
	return $content . '}';
}

/**
 * 获取模版文件 格式 资源://模块@主题/控制器/操作
 *
 * @param string $template
 *        	模版资源地址
 * @param string $layer
 *        	视图层（目录）名称
 * @return string
 */
function T($template = '', $layer = '') {
	// weiphp增加对插件模板的调用
	$temp_fix = C ( 'TMPL_TEMPLATE_SUFFIX' );
	if (false !== strpos ( $template, 'Addons/' ) && false === strpos ( $template, '://' ) && false === strpos ( $template, '@' )) {
		$file_path = APP_PATH . 'Home/View/' . $template . $temp_fix;
		return $file_path;
	}
	
	// 解析模版资源地址
	if (false === strpos ( $template, '://' )) {
		$template = HTTP_PREFIX . str_replace ( ':', '/', $template );
	}
	$info = parse_url ( $template );
	$file = $info ['host'] . (isset ( $info ['path'] ) ? $info ['path'] : '');
	$module = isset ( $info ['user'] ) ? $info ['user'] . '/' : MODULE_NAME . '/';
	$extend = $info ['scheme'];
	$layer = $layer ? $layer : C ( 'DEFAULT_V_LAYER' );
	
	// 获取当前主题的模版路径
	$auto = C ( 'AUTOLOAD_NAMESPACE' );
	if ($auto && isset ( $auto [$extend] )) { // 扩展资源
		$baseUrl = $auto [$extend] . $module . $layer . '/';
	} elseif (C ( 'VIEW_PATH' )) {
		// 改变模块视图目录
		$baseUrl = C ( 'VIEW_PATH' );
	} elseif (defined ( 'TMPL_PATH' )) {
		// 指定全局视图目录
		$baseUrl = TMPL_PATH . $module;
	} elseif (is_dir ( ADDON_PATH . $module . $layer )) {
		// weiphp补充，增加对addons下的模板的支持
		$baseUrl = ADDON_PATH . $module . $layer . '/';
	} else {
		$baseUrl = APP_PATH . $module . $layer . '/';
	}
	
	// 获取主题
	$theme = substr_count ( $file, '/' ) < 2 ? C ( 'DEFAULT_THEME' ) : '';
	
	// 分析模板文件规则
	$depr = C ( 'TMPL_FILE_DEPR' );
	if ('' == $file) {
		// 如果模板文件名为空 按照默认规则定位
		$file = CONTROLLER_NAME . $depr . ACTION_NAME;
	} elseif (false === strpos ( $file, '/' )) {
		$file = CONTROLLER_NAME . $depr . $file;
	} elseif ('/' != $depr) {
		$file = substr_count ( $file, '/' ) > 1 ? substr_replace ( $file, $depr, strrpos ( $file, '/' ), 1 ) : str_replace ( '/', $depr, $file );
	}
	
	return $baseUrl . ($theme ? $theme . '/' : '') . $file . $temp_fix;
}

/**
 * 获取输入参数 支持过滤和默认值
 * 使用方法:
 * <code>
 * I('id',0); 获取id参数 自动判断get或者post
 * I('post.name','','htmlspecialchars'); 获取$_POST['name']
 * I('get.'); 获取$_GET
 * </code>
 *
 * @param string $name
 *        	变量的名称 支持指定类型
 * @param mixed $default
 *        	不存在的时候默认值
 * @param mixed $filter
 *        	参数过滤方法
 * @param mixed $datas
 *        	要获取的额外数据源
 * @return mixed
 */
function I($name, $default = '', $filter = null, $datas = null) {
	if (strpos ( $name, '.' )) { // 指定参数来源
		list ( $method, $name ) = explode ( '.', $name, 2 );
	} else { // 默认为自动判断
		$method = 'param';
	}
	switch (strtolower ( $method )) {
		case 'get' :
			$input = & $_GET;
			break;
		case 'post' :
			$input = & $_POST;
			break;
		case 'put' :
			parse_str ( file_get_contents ( 'php://input' ), $input );
			break;
		case 'param' :
			switch ($_SERVER ['REQUEST_METHOD']) {
				case 'POST' :
					$input = $_POST;
					break;
				case 'PUT' :
					parse_str ( file_get_contents ( 'php://input' ), $input );
					break;
				default :
					$input = $_GET;
			}
			break;
		case 'path' :
			$input = array ();
			if (! empty ( $_SERVER ['PATH_INFO'] )) {
				$depr = C ( 'URL_PATHINFO_DEPR' );
				$input = explode ( $depr, trim ( $_SERVER ['PATH_INFO'], $depr ) );
			}
			break;
		case 'request' :
			$input = & $_REQUEST;
			break;
		case 'session' :
			$input = & $_SESSION;
			break;
		case 'cookie' :
			$input = & $_COOKIE;
			break;
		case 'server' :
			$input = & $_SERVER;
			break;
		case 'globals' :
			$input = & $GLOBALS;
			break;
		case 'data' :
			$input = & $datas;
			break;
		default :
			return NULL;
	}
	if ('' == $name) { // 获取全部变量
		$data = $input;
		array_walk_recursive ( $data, 'filter_exp' );
		$filters = isset ( $filter ) ? $filter : C ( 'DEFAULT_FILTER' );
		if ($filters) {
			if (is_string ( $filters )) {
				$filters = explode ( ',', $filters );
			}
			foreach ( $filters as $filter ) {
				$data = array_map_recursive ( $filter, $data ); // 参数过滤
			}
		}
	} elseif (isset ( $input [$name] )) { // 取值操作
		$data = $input [$name];
		is_array ( $data ) && array_walk_recursive ( $data, 'filter_exp' );
		$filters = isset ( $filter ) ? $filter : C ( 'DEFAULT_FILTER' );
		if ($filters) {
			if (is_string ( $filters )) {
				$filters = explode ( ',', $filters );
			} elseif (is_int ( $filters )) {
				$filters = array (
						$filters 
				);
			}
			
			foreach ( $filters as $filter ) {
				if (function_exists ( $filter )) {
					$data = is_array ( $data ) ? array_map_recursive ( $filter, $data ) : $filter ( $data ); // 参数过滤
				} else {
					$data = filter_var ( $data, is_int ( $filter ) ? $filter : filter_id ( $filter ) );
					if (false === $data) {
						return isset ( $default ) ? $default : NULL;
					}
				}
			}
		}
	} else { // 变量默认值
		$data = isset ( $default ) ? $default : NULL;
	}
	return $data;
}
function array_map_recursive($filter, $data) {
	$result = array ();
	foreach ( $data as $key => $val ) {
		$result [$key] = is_array ( $val ) ? array_map_recursive ( $filter, $val ) : call_user_func ( $filter, $val );
	}
	return $result;
}

/**
 * 设置和获取统计数据
 * 使用方法:
 * <code>
 * N('db',1); // 记录数据库操作次数
 * N('read',1); // 记录读取次数
 * echo N('db'); // 获取当前页面数据库的所有操作次数
 * echo N('read'); // 获取当前页面读取次数
 * </code>
 *
 * @param string $key
 *        	标识位置
 * @param integer $step
 *        	步进值
 * @param boolean $save
 *        	是否保存结果
 * @return mixed
 */
function N($key, $step = 0, $save = false) {
	static $_num = array ();
	if (! isset ( $_num [$key] )) {
		$_num [$key] = (false !== $save) ? S ( 'N_' . $key ) : 0;
	}
	if (empty ( $step )) {
		return $_num [$key];
	} else {
		$_num [$key] = $_num [$key] + ( int ) $step;
	}
	if (false !== $save) { // 保存结果
		S ( 'N_' . $key, $_num [$key], $save );
	}
	return null;
}

/**
 * 字符串命名风格转换
 * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
 *
 * @param string $name
 *        	字符串
 * @param integer $type
 *        	转换类型
 * @return string
 */
function parse_name($name, $type = 0) {
	if ($type) {
		return ucfirst ( preg_replace_callback ( '/_([a-zA-Z])/', function ($match) {
			return strtoupper ( $match [1] );
		}, $name ) );
	} else {
		return strtolower ( trim ( preg_replace ( "/[A-Z]/", "_\\0", $name ), "_" ) );
	}
}

/**
 * 优化的require_once
 *
 * @param string $filename
 *        	文件地址
 * @return boolean
 */
function require_cache($filename) {
	static $_importFiles = array ();
	if (! isset ( $_importFiles [$filename] )) {
		if (file_exists_case ( $filename )) {
			require $filename;
			$_importFiles [$filename] = true;
		} else {
			$_importFiles [$filename] = false;
		}
	}
	return $_importFiles [$filename];
}

/**
 * 区分大小写的文件存在判断
 *
 * @param string $filename
 *        	文件地址
 * @return boolean
 */
function file_exists_case($filename) {
	if (is_file ( $filename )) {
		if (IS_WIN && APP_DEBUG) {
			if (basename ( realpath ( $filename ) ) != basename ( $filename ))
				return false;
		}
		return true;
	}
	return false;
}

/**
 * 导入所需的类库 同java的Import 本函数有缓存功能
 *
 * @param string $class
 *        	类库命名空间字符串
 * @param string $baseUrl
 *        	起始路径
 * @param string $ext
 *        	导入的文件扩展名
 * @return boolean
 */
function import($class, $baseUrl = '', $ext = EXT) {
	static $_file = array ();
	$class = str_replace ( array (
			'.',
			'#' 
	), array (
			'/',
			'.' 
	), $class );
	if (isset ( $_file [$class . $baseUrl] ))
		return true;
	else
		$_file [$class . $baseUrl] = true;
	$class_strut = explode ( '/', $class );
	if (empty ( $baseUrl )) {
		if ('@' == $class_strut [0] || MODULE_NAME == $class_strut [0]) {
			// 加载当前模块的类库
			$baseUrl = MODULE_PATH;
			$class = substr_replace ( $class, '', 0, strlen ( $class_strut [0] ) + 1 );
		} elseif ('Common' == $class_strut [0]) {
			// 加载公共模块的类库
			$baseUrl = COMMON_PATH;
			$class = substr ( $class, 7 );
		} elseif (in_array ( $class_strut [0], array (
				'Think',
				'Org',
				'Behavior',
				'Com',
				'Vendor' 
		) ) || is_dir ( LIB_PATH . $class_strut [0] )) {
			// 系统类库包和第三方类库包
			$baseUrl = LIB_PATH;
		} else { // 加载其他模块的类库
			$baseUrl = APP_PATH;
		}
	}
	if (substr ( $baseUrl, - 1 ) != '/')
		$baseUrl .= '/';
	$classfile = $baseUrl . $class . $ext;
	if (! class_exists ( basename ( $class ), false )) {
		// 如果类不存在 则导入类库文件
		return require_cache ( $classfile );
	}
	return null;
}

/**
 * 基于命名空间方式导入函数库
 * load('@.Util.Array')
 *
 * @param string $name
 *        	函数库命名空间字符串
 * @param string $baseUrl
 *        	起始路径
 * @param string $ext
 *        	导入的文件扩展名
 * @return void
 */
function load($name, $baseUrl = '', $ext = '.php') {
	$name = str_replace ( array (
			'.',
			'#' 
	), array (
			'/',
			'.' 
	), $name );
	if (empty ( $baseUrl )) {
		if (0 === strpos ( $name, '@/' )) { // 加载当前模块函数库
			$baseUrl = MODULE_PATH . 'Common/';
			$name = substr ( $name, 2 );
		} else { // 加载其他模块函数库
			$array = explode ( '/', $name );
			$baseUrl = APP_PATH . array_shift ( $array ) . '/Common/';
			$name = implode ( '/', $array );
		}
	}
	if (substr ( $baseUrl, - 1 ) != '/')
		$baseUrl .= '/';
	require_cache ( $baseUrl . $name . $ext );
}

/**
 * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面
 *
 * @param string $class
 *        	类库
 * @param string $baseUrl
 *        	基础目录
 * @param string $ext
 *        	类库后缀
 * @return boolean
 */
function vendor($class, $baseUrl = '', $ext = '.php') {
	if (empty ( $baseUrl ))
		$baseUrl = VENDOR_PATH;
	return import ( $class, $baseUrl, $ext );
}

/**
 * 实例化模型类 格式 [资源://][模块/]模型
 *
 * @param string $name
 *        	资源地址
 * @param string $layer
 *        	模型层名称
 * @return Think\Model
 */
function D($name = '', $layer = '') {
	if (empty ( $name ))
		return new Think\Model ();
	static $_model = array ();
	$layer = $layer ?: C ( 'DEFAULT_M_LAYER' );
	if (isset ( $_model [$name . $layer] ))
		return $_model [$name . $layer];
	$class = parse_res_name ( $name, $layer );
	
	$class_addon = '';
	if (defined ( 'MODULE_NAME' )) {
		$class_addon = parse_res_name ( 'Addons://' . MODULE_NAME . '/' . $name, $layer );
	}
	
	if ($class_addon && class_exists ( $class_addon )) {
		$model = new $class_addon ( basename ( $name ) );
	} elseif (class_exists ( $class )) {
		$model = new $class ( basename ( $name ) );
	} elseif (false === strpos ( $name, '/' )) {
		// 自动加载公共模块下面的模型
		if (! C ( 'APP_USE_NAMESPACE' )) {
			import ( 'Common/' . $layer . '/' . $class );
		} else {
			$class = '\\Common\\' . $layer . '\\' . $name . $layer;
		}
		$model = class_exists ( $class ) ? new $class ( $name ) : new Think\Model ( $name );
	} else {
		Think\Log::record ( 'D方法实例化没找到模型类' . $class, Think\Log::NOTICE );
		$model = new Think\Model ( basename ( $name ) );
	}
	$_model [$name . $layer] = $model;
	return $model;
}

/**
 * 实例化一个没有模型文件的Model
 *
 * @param string $name
 *        	Model名称 支持指定基础模型 例如 MongoModel:User
 * @param string $tablePrefix
 *        	表前缀
 * @param mixed $connection
 *        	数据库连接信息
 * @return Think\Model
 */
function M($name = '', $tablePrefix = '', $connection = '') {
	static $_model = array ();
	if (strpos ( $name, ':' )) {
		list ( $class, $name ) = explode ( ':', $name );
	} else {
		$class = 'Think\\Model';
	}
	$guid = (is_array ( $connection ) ? implode ( '', $connection ) : $connection) . $tablePrefix . $name . '_' . $class;
	if (! isset ( $_model [$guid] ))
		$_model [$guid] = new $class ( $name, $tablePrefix, $connection );
	return $_model [$guid];
}

/**
 * 解析资源地址并导入类库文件
 * 例如 module/controller addon://module/behavior
 *
 * @param string $name
 *        	资源地址 格式：[扩展://][模块/]资源名
 * @param string $layer
 *        	分层名称
 * @param integer $level
 *        	控制器层次
 * @return string
 */
function parse_res_name($name, $layer, $level = 1) {
	if (strpos ( $name, '://' )) { // 指定扩展资源
		list ( $extend, $name ) = explode ( '://', $name );
	} else {
		$extend = '';
	}
	if (strpos ( $name, '/' ) && substr_count ( $name, '/' ) >= $level) { // 指定模块
		list ( $module, $name ) = explode ( '/', $name, 2 );
	} else {
		$module = defined ( 'MODULE_NAME' ) ? MODULE_NAME : '';
	}
	$array = explode ( '/', $name );
	if (! C ( 'APP_USE_NAMESPACE' )) {
		$class = parse_name ( $name, 1 );
		import ( $module . '/' . $layer . '/' . $class . $layer );
	} else {
		$class = $module . '\\' . $layer;
		foreach ( $array as $name ) {
			$class .= '\\' . parse_name ( $name, 1 );
		}
		// 导入资源类库
		if ($extend) { // 扩展资源
			$class = $extend . '\\' . $class;
		}
	}
	return $class . $layer;
}

/**
 * 用于实例化访问控制器
 *
 * @param string $name
 *        	控制器名
 * @param string $path
 *        	控制器命名空间（路径）
 * @return Think\Controller|false
 */
function controller($name, $path = '') {
	$layer = C ( 'DEFAULT_C_LAYER' );
	if (! C ( 'APP_USE_NAMESPACE' )) {
		$class = parse_name ( $name, 1 ) . $layer;
		import ( MODULE_NAME . '/' . $layer . '/' . $class );
	} else {
		$class = ($path ? basename ( ADDON_PATH ) . '\\' . $path : MODULE_NAME) . '\\' . $layer;
		$array = explode ( '/', $name );
		foreach ( $array as $name ) {
			$class .= '\\' . parse_name ( $name, 1 );
		}
		$class .= $layer;
	}
	if (class_exists ( $class )) {
		return new $class ();
	} else {
		return false;
	}
}

/**
 * 实例化多层控制器 格式：[资源://][模块/]控制器
 *
 * @param string $name
 *        	资源地址
 * @param string $layer
 *        	控制层名称
 * @param integer $level
 *        	控制器层次
 * @return Think\Controller|false
 */
function A($name, $layer = '', $level = 0) {
	static $_action = array ();
	$layer = $layer ?: C ( 'DEFAULT_C_LAYER' );
	$level = $level ?: ($layer == C ( 'DEFAULT_C_LAYER' ) ? C ( 'CONTROLLER_LEVEL' ) : 1);
	if (isset ( $_action [$name . $layer] ))
		return $_action [$name . $layer];
	
	$class = parse_res_name ( $name, $layer, $level );
	
	if (class_exists ( $class )) {
		$action = new $class ();
		$_action [$name . $layer] = $action;
		return $action;
	} else {
		return false;
	}
}

/**
 * 远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作
 *
 * @param string $url
 *        	调用地址
 * @param string|array $vars
 *        	调用参数 支持字符串和数组
 * @param string $layer
 *        	要调用的控制层名称
 * @return mixed
 */
function R($url, $vars = array(), $layer = '') {
	$info = pathinfo ( $url );
	$action = $info ['basename'];
	$module = $info ['dirname'];
	$class = A ( $module, $layer );
	
	if ($class) {
		if (is_string ( $vars )) {
			parse_str ( $vars, $vars );
		}
		return call_user_func_array ( array (
				&$class,
				$action . C ( 'ACTION_SUFFIX' ) 
		), $vars );
	} else {
		return false;
	}
}

/**
 * 处理标签扩展
 *
 * @param string $tag
 *        	标签名称
 * @param mixed $params
 *        	传入参数
 * @return void
 */
function tag($tag, &$params = NULL) {
	\Think\Hook::listen ( $tag, $params );
}

/**
 * 执行某个行为
 *
 * @param string $name
 *        	行为名称
 * @param string $tag
 *        	标签名称（行为类无需传入）
 * @param Mixed $params
 *        	传入的参数
 * @return void
 */
function B($name, $tag = '', &$params = NULL) {
	if ('' == $tag) {
		$name .= 'Behavior';
	}
	\Think\Hook::exec ( $name, $tag, $params );
}

/**
 * 去除代码中的空白和注释
 *
 * @param string $content
 *        	代码内容
 * @return string
 */
function strip_whitespace($content) {
	$stripStr = '';
	// 分析php源码
	$tokens = token_get_all ( $content );
	$last_space = false;
	for($i = 0, $j = count ( $tokens ); $i < $j; $i ++) {
		if (is_string ( $tokens [$i] )) {
			$last_space = false;
			$stripStr .= $tokens [$i];
		} else {
			switch ($tokens [$i] [0]) {
				// 过滤各种PHP注释
				case T_COMMENT :
				case T_DOC_COMMENT :
					break;
				// 过滤空格
				case T_WHITESPACE :
					if (! $last_space) {
						$stripStr .= ' ';
						$last_space = true;
					}
					break;
				case T_START_HEREDOC :
					$stripStr .= "<<<THINK\n";
					break;
				case T_END_HEREDOC :
					$stripStr .= "THINK;\n";
					for($k = $i + 1; $k < $j; $k ++) {
						if (is_string ( $tokens [$k] ) && $tokens [$k] == ';') {
							$i = $k;
							break;
						} else if ($tokens [$k] [0] == T_CLOSE_TAG) {
							break;
						}
					}
					break;
				default :
					$last_space = false;
					$stripStr .= $tokens [$i] [1];
			}
		}
	}
	return $stripStr;
}

/**
 * 自定义异常处理
 *
 * @param string $msg
 *        	异常消息
 * @param string $type
 *        	异常类型 默认为Think\Exception
 * @param integer $code
 *        	异常代码 默认为0
 * @return void
 */
function throw_exception($msg, $type = 'Think\\Exception', $code = 0) {
	Think\Log::record ( '建议使用E方法替代throw_exception', Think\Log::NOTICE );
	if (class_exists ( $type, false ))
		throw new $type ( $msg, $code );
	else
		Think\Think::halt ( $msg ); // 异常类型不存在则输出错误信息字串
}

/**
 * 浏览器友好的变量输出
 *
 * @param mixed $var
 *        	变量
 * @param boolean $echo
 *        	是否输出 默认为True 如果为false 则返回输出字符串
 * @param string $label
 *        	标签 默认为空
 * @param boolean $strict
 *        	是否严谨 默认为true
 * @return void|string
 */
function dump($var, $echo = true, $label = null, $strict = true) {
	$label = ($label === null) ? '' : rtrim ( $label ) . ' ';
	if (! $strict) {
		if (ini_get ( 'html_errors' )) {
			$output = print_r ( $var, true );
			$output = '<pre>' . $label . htmlspecialchars ( $output, ENT_QUOTES ) . '</pre>';
		} else {
			$output = $label . print_r ( $var, true );
		}
	} else {
		ob_start ();
		var_dump ( $var );
		$output = ob_get_clean ();
		if (! extension_loaded ( 'xdebug' )) {
			$output = preg_replace ( '/\]\=\>\n(\s+)/m', '] => ', $output );
			$output = '<pre>' . $label . htmlspecialchars ( $output, ENT_QUOTES ) . '</pre>';
		}
	}
	if ($echo) {
		echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
		echo ($output);
		return null;
	} else
		return $output;
}

/**
 * 设置当前页面的布局
 *
 * @param string|false $layout
 *        	布局名称 为false的时候表示关闭布局
 * @return void
 */
function layout($layout) {
	if (false !== $layout) {
		// 开启布局
		C ( 'LAYOUT_ON', true );
		if (is_string ( $layout )) { // 设置新的布局模板
			C ( 'LAYOUT_NAME', $layout );
		}
	} else { // 临时关闭布局
		C ( 'LAYOUT_ON', false );
	}
}

/**
 * URL组装 支持不同URL模式
 *
 * @param string $url
 *        	URL表达式，格式：'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
 * @param string|array $vars
 *        	传入的参数，支持数组和字符串
 * @param string|boolean $suffix
 *        	伪静态后缀，默认为true表示获取配置值
 * @param boolean $domain
 *        	是否显示域名
 * @return string
 */
function U($url = '', $vars = '', $suffix = true, $domain = true) {
	// 解析URL
	$info = parse_url ( $url );
	
	$url = ! empty ( $info ['path'] ) ? $info ['path'] : ACTION_NAME;
	if (isset ( $info ['fragment'] )) { // 解析锚点
		$anchor = $info ['fragment'];
		if (false !== strpos ( $anchor, '?' )) { // 解析参数
			list ( $anchor, $info ['query'] ) = explode ( '?', $anchor, 2 );
		}
		if (false !== strpos ( $anchor, '@' )) { // 解析域名
			list ( $anchor, $host ) = explode ( '@', $anchor, 2 );
		}
	} elseif (false !== strpos ( $url, '@' )) { // 解析域名
		list ( $url, $host ) = explode ( '@', $info ['path'], 2 );
	}
	// 解析子域名
	if (isset ( $host )) {
		$domain = $host . (strpos ( $host, '.' ) ? '' : strstr ( $_SERVER ['HTTP_HOST'], '.' ));
	} elseif ($domain === true) {
		$domain = $_SERVER ['HTTP_HOST'];
		if (C ( 'APP_SUB_DOMAIN_DEPLOY' )) { // 开启子域名部署
			$domain = $domain == 'localhost' ? 'localhost' : 'www' . strstr ( $_SERVER ['HTTP_HOST'], '.' );
			// '子域名'=>array('模块[/控制器]');
			foreach ( C ( 'APP_SUB_DOMAIN_RULES' ) as $key => $rule ) {
				$rule = is_array ( $rule ) ? $rule [0] : $rule;
				if (false === strpos ( $key, '*' ) && 0 === strpos ( $url, $rule )) {
					$domain = $key . strstr ( $domain, '.' ); // 生成对应子域名
					$url = substr_replace ( $url, '', 0, strlen ( $rule ) );
					break;
				}
			}
		}
	}
	
	// 解析参数
	if (is_string ( $vars )) { // aaa=1&bbb=2 转换成数组
		parse_str ( $vars, $vars );
	} elseif (! is_array ( $vars )) {
		$vars = array ();
	}
	if (isset ( $info ['query'] )) { // 解析地址里面参数 合并到vars
		parse_str ( $info ['query'], $params );
		$vars = array_merge ( $params, $vars );
	}
	
	// URL组装
	$depr = C ( 'URL_PATHINFO_DEPR' );
	$urlCase = C ( 'URL_CASE_INSENSITIVE' );
	if ($url) {
		if (0 === strpos ( $url, '/' )) { // 定义路由
			$route = true;
			$url = substr ( $url, 1 );
			if ('/' != $depr) {
				$url = str_replace ( '/', $depr, $url );
			}
		} else {
			if ('/' != $depr) { // 安全替换
				$url = str_replace ( '/', $depr, $url );
			}
			// 解析模块、控制器和操作
			$url = trim ( $url, $depr );
			$path = explode ( $depr, $url );
			$var = array ();
			$varModule = C ( 'VAR_MODULE' );
			$varController = C ( 'VAR_CONTROLLER' );
			$varAction = C ( 'VAR_ACTION' );
			$var [$varAction] = ! empty ( $path ) ? array_pop ( $path ) : ACTION_NAME;
			$var [$varController] = ! empty ( $path ) ? array_pop ( $path ) : CONTROLLER_NAME;
			if ($maps = C ( 'URL_ACTION_MAP' )) {
				if (isset ( $maps [strtolower ( $var [$varController] )] )) {
					$maps = $maps [strtolower ( $var [$varController] )];
					if ($action = array_search ( strtolower ( $var [$varAction] ), $maps )) {
						$var [$varAction] = $action;
					}
				}
			}
			if ($maps = C ( 'URL_CONTROLLER_MAP' )) {
				if ($controller = array_search ( strtolower ( $var [$varController] ), $maps )) {
					$var [$varController] = $controller;
				}
			}
			if ($urlCase) {
				$var [$varController] = parse_name ( $var [$varController] );
			}
			$module = '';
			
			if (! empty ( $path )) {
				$var [$varModule] = implode ( $depr, $path );
			} else {
				if (C ( 'MULTI_MODULE' )) {
					if (MODULE_NAME != C ( 'DEFAULT_MODULE' ) || ! C ( 'MODULE_ALLOW_LIST' )) {
						$var [$varModule] = MODULE_NAME;
					}
				}
			}
			if ($maps = C ( 'URL_MODULE_MAP' )) {
				if ($_module = array_search ( strtolower ( $var [$varModule] ), $maps )) {
					$var [$varModule] = $_module;
				}
			}
			if (isset ( $var [$varModule] )) {
				$module = $var [$varModule];
				unset ( $var [$varModule] );
			}
		}
	}
	
	if (isset ( $vars ['token'] )) {
		$wpid = get_token_appinfo ( $vars ['token'], 'id' );
		unset ( $vars ['token'] );
	} elseif (isset ( $vars ['publicid'] )) {
		$wpid = $vars ['publicid'];
		unset ( $vars ['publicid'] );
	} elseif (isset ( $vars ['wpid'] )) {
		$wpid = $vars ['wpid'];
		unset ( $vars ['wpid'] );
	} else {
		$wpid = intval ( WPID );
	}
	if (C ( 'URL_MODEL' ) == 0) { // 普通模式URL转换
		$url = __APP__ . '?' . C ( 'VAR_MODULE' ) . "={$module}&" . http_build_query ( array_reverse ( $var ) );
		if ($urlCase) {
			$url = strtolower ( $url );
		}
		if (! empty ( $vars )) {
			$vars = http_build_query ( $vars );
			$url .= '&' . $vars;
		}
	} else { // PATHINFO模式或者兼容URL模式
		if (isset ( $route )) {
			$url = __APP__ . '/' . rtrim ( $url, $depr );
		} else {
			$module = (defined ( 'BIND_MODULE' ) && BIND_MODULE == $module) ? '' : $module;
			
			// 强制加上appid的信息
			$url = __APP__ . '/w' . $wpid . '/' . ($module ? $module . MODULE_PATHINFO_DEPR : '') . implode ( $depr, array_reverse ( $var ) );
		}
		if ($urlCase) {
			$url = strtolower ( $url );
		}
		if (! empty ( $vars )) { // 添加参数
			foreach ( $vars as $var => $val ) {
				if ('' !== trim ( $val ))
					$url .= $depr . $var . $depr . urlencode ( $val );
			}
		}
		if ($suffix) {
			$suffix = $suffix === true ? C ( 'URL_HTML_SUFFIX' ) : $suffix;
			if ($pos = strpos ( $suffix, '|' )) {
				$suffix = substr ( $suffix, 0, $pos );
			}
			if ($suffix && '/' != substr ( $url, - 1 )) {
				$url .= '.' . ltrim ( $suffix, '.' );
			}
		}
	}
	if (isset ( $anchor )) {
		$url .= '#' . $anchor;
	}
	
	if ($domain) {
		$url = (is_ssl () ? 'https://' : 'http://') . $domain . $url;
	}
	
	// 20170105 凡星
	if (HTTP_PREFIX == 'https://' && false === strpos ( $url, 'https' )) {
		$url = str_replace ( 'http', 'https', $url );
	}
	return $url;
}

/**
 * 渲染输出Widget
 *
 * @param string $name
 *        	Widget名称
 * @param array $data
 *        	传入的参数
 * @return void
 */
function W($name, $data = array()) {
	$data = array (
			$data 
	);
	$name = 'Common/' . $name . '/run';
	R ( $name, $data, 'Widget' );
}

/**
 * 判断是否SSL协议
 *
 * @return boolean
 */
function is_ssl() {
	if (isset ( $_SERVER ['HTTPS'] ) && ('1' == $_SERVER ['HTTPS'] || 'on' == strtolower ( $_SERVER ['HTTPS'] ))) {
		return true;
	} elseif (isset ( $_SERVER ['SERVER_PORT'] ) && ('443' == $_SERVER ['SERVER_PORT'])) {
		return true;
	}
	return false;
}

/**
 * URL重定向
 *
 * @param string $url
 *        	重定向的URL地址
 * @param integer $time
 *        	重定向的等待时间（秒）
 * @param string $msg
 *        	重定向前的提示信息
 * @return void
 */
function redirect($url, $time = 0, $msg = '') {
	// 多行URL地址支持
	$url = str_replace ( array (
			"\n",
			"\r" 
	), '', $url );
	if (empty ( $msg ))
		$msg = "系统将在{$time}秒之后自动跳转到{$url}！";
	if (! headers_sent ()) {
		// redirect
		if (0 === $time) {
			header ( 'Location: ' . $url );
		} else {
			header ( "refresh:{$time};url={$url}" );
			echo ($msg);
		}
		exit ();
	} else {
		$str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
		if ($time != 0)
			$str .= $msg;
		exit ( $str );
	}
}

/**
 * 缓存管理
 *
 * @param mixed $name
 *        	缓存名称，如果为数组表示进行缓存设置
 * @param mixed $value
 *        	缓存值
 * @param mixed $options
 *        	缓存参数
 * @return mixed
 */
function S($name, $value = '', $options = null) {
	static $cache = '';
	if (is_array ( $options ) && empty ( $cache )) {
		// 缓存操作的同时初始化
		$type = isset ( $options ['type'] ) ? $options ['type'] : '';
		$cache = Think\Cache::getInstance ( $type, $options );
	} elseif (is_array ( $name )) { // 缓存初始化
		$type = isset ( $name ['type'] ) ? $name ['type'] : '';
		$cache = Think\Cache::getInstance ( $type, $name );
		return $cache;
	} elseif (empty ( $cache )) { // 自动初始化
		$cache = Think\Cache::getInstance ();
	}
	if ('' === $value) { // 获取缓存
		return $cache->get ( $name );
	} elseif (is_null ( $value )) { // 删除缓存
		return $cache->rm ( $name );
	} else { // 缓存数据
		if (is_array ( $options )) {
			$expire = isset ( $options ['expire'] ) ? $options ['expire'] : NULL;
		} else {
			$expire = is_numeric ( $options ) ? $options : NULL;
		}
		return $cache->set ( $name, $value, $expire );
	}
}

/**
 * 快速文件数据读取和保存 针对简单类型数据 字符串、数组
 *
 * @param string $name
 *        	缓存名称
 * @param mixed $value
 *        	缓存值
 * @param string $path
 *        	缓存路径
 * @return mixed
 */
function F($name, $value = '', $path = DATA_PATH) {
	static $_cache = array ();
	$filename = $path . $name . '.php';
	if ('' !== $value) {
		if (is_null ( $value )) {
			// 删除缓存
			if (false !== strpos ( $name, '*' )) {
				return false; // TODO
			} else {
				unset ( $_cache [$name] );
				return Think\Storage::unlink ( $filename, 'F' );
			}
		} else {
			Think\Storage::put ( $filename, serialize ( $value ), 'F' );
			// 缓存数据
			$_cache [$name] = $value;
			return null;
		}
	}
	// 获取缓存数据
	if (isset ( $_cache [$name] ))
		return $_cache [$name];
	if (Think\Storage::has ( $filename, 'F' )) {
		$value = unserialize ( Think\Storage::read ( $filename, 'F' ) );
		$_cache [$name] = $value;
	} else {
		$value = false;
	}
	return $value;
}

/**
 * 根据PHP各种类型变量生成唯一标识号
 *
 * @param mixed $mix
 *        	变量
 * @return string
 */
function to_guid_string($mix) {
	if (is_object ( $mix )) {
		return spl_object_hash ( $mix );
	} elseif (is_resource ( $mix )) {
		$mix = get_resource_type ( $mix ) . strval ( $mix );
	} else {
		$mix = serialize ( $mix );
	}
	return md5 ( $mix );
}

/**
 * XML编码
 *
 * @param mixed $data
 *        	数据
 * @param string $root
 *        	根节点名
 * @param string $item
 *        	数字索引的子节点名
 * @param string $attr
 *        	根节点属性
 * @param string $id
 *        	数字索引子节点key转换的属性名
 * @param string $encoding
 *        	数据编码
 * @return string
 */
function xml_encode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') {
	if (is_array ( $attr )) {
		$_attr = array ();
		foreach ( $attr as $key => $value ) {
			$_attr [] = "{$key}=\"{$value}\"";
		}
		$attr = implode ( ' ', $_attr );
	}
	$attr = trim ( $attr );
	$attr = empty ( $attr ) ? '' : " {$attr}";
	$xml = "<?xml version=\"1.0\" encoding=\"{$encoding}\"?>";
	$xml .= "<{$root}{$attr}>";
	$xml .= data_to_xml ( $data, $item, $id );
	$xml .= "</{$root}>";
	return $xml;
}

/**
 * 数据XML编码
 *
 * @param mixed $data
 *        	数据
 * @param string $item
 *        	数字索引时的节点名称
 * @param string $id
 *        	数字索引key转换为的属性名
 * @return string
 */
function data_to_xml($data, $item = 'item', $id = 'id') {
	$xml = $attr = '';
	foreach ( $data as $key => $val ) {
		if (is_numeric ( $key )) {
			$id && $attr = " {$id}=\"{$key}\"";
			$key = $item;
		}
		$xml .= "<{$key}{$attr}>";
		$xml .= (is_array ( $val ) || is_object ( $val )) ? data_to_xml ( $val, $item, $id ) : $val;
		$xml .= "</{$key}>";
	}
	return $xml;
}

/**
 * session管理函数
 *
 * @param string|array $name
 *        	session名称 如果为数组则表示进行session设置
 * @param mixed $value
 *        	session值
 * @return mixed
 */
function session($name = '', $value = '') {
	$prefix = C ( 'SESSION_PREFIX' );
	if (is_array ( $name )) { // session初始化 在session_start 之前调用
		if (isset ( $name ['prefix'] ))
			C ( 'SESSION_PREFIX', $name ['prefix'] );
		if (C ( 'VAR_SESSION_ID' ) && isset ( $_REQUEST [C ( 'VAR_SESSION_ID' )] )) {
			session_id ( $_REQUEST [C ( 'VAR_SESSION_ID' )] );
		} elseif (isset ( $name ['id'] )) {
			session_id ( $name ['id'] );
		}
		if ('common' != APP_MODE) { // 其它模式可能不支持
			ini_set ( 'session.auto_start', 0 );
		}
		if (isset ( $name ['name'] ))
			session_name ( $name ['name'] );
		if (isset ( $name ['path'] ))
			session_save_path ( $name ['path'] );
		if (isset ( $name ['domain'] ))
			ini_set ( 'session.cookie_domain', $name ['domain'] );
		if (isset ( $name ['expire'] ))
			ini_set ( 'session.gc_maxlifetime', $name ['expire'] );
		if (isset ( $name ['use_trans_sid'] ))
			ini_set ( 'session.use_trans_sid', $name ['use_trans_sid'] ? 1 : 0 );
		if (isset ( $name ['use_cookies'] ))
			ini_set ( 'session.use_cookies', $name ['use_cookies'] ? 1 : 0 );
		if (isset ( $name ['cache_limiter'] ))
			session_cache_limiter ( $name ['cache_limiter'] );
		if (isset ( $name ['cache_expire'] ))
			session_cache_expire ( $name ['cache_expire'] );
		if (isset ( $name ['type'] ))
			C ( 'SESSION_TYPE', $name ['type'] );
		if (C ( 'SESSION_TYPE' )) { // 读取session驱动
			$type = C ( 'SESSION_TYPE' );
			$class = strpos ( $type, '\\' ) ? $type : 'Think\\Session\\Driver\\' . ucwords ( strtolower ( $type ) );
			$hander = new $class ();
			session_set_save_handler ( array (
					&$hander,
					"open" 
			), array (
					&$hander,
					"close" 
			), array (
					&$hander,
					"read" 
			), array (
					&$hander,
					"write" 
			), array (
					&$hander,
					"destroy" 
			), array (
					&$hander,
					"gc" 
			) );
		}
		// 启动session
		if (C ( 'SESSION_AUTO_START' ))
			session_start ();
	} elseif ('' === $value) {
		if ('' === $name) {
			// 获取全部的session
			return $prefix ? $_SESSION [$prefix] : $_SESSION;
		} elseif (0 === strpos ( $name, '[' )) { // session 操作
			if ('[pause]' == $name) { // 暂停session
				session_write_close ();
			} elseif ('[start]' == $name) { // 启动session
				session_start ();
			} elseif ('[destroy]' == $name) { // 销毁session
				$_SESSION = array ();
				session_unset ();
				session_destroy ();
			} elseif ('[regenerate]' == $name) { // 重新生成id
				session_regenerate_id ();
			}
		} elseif (0 === strpos ( $name, '?' )) { // 检查session
			$name = substr ( $name, 1 );
			if (strpos ( $name, '.' )) { // 支持数组
				list ( $name1, $name2 ) = explode ( '.', $name );
				return $prefix ? isset ( $_SESSION [$prefix] [$name1] [$name2] ) : isset ( $_SESSION [$name1] [$name2] );
			} else {
				return $prefix ? isset ( $_SESSION [$prefix] [$name] ) : isset ( $_SESSION [$name] );
			}
		} elseif (is_null ( $name )) { // 清空session
			if ($prefix) {
				unset ( $_SESSION [$prefix] );
			} else {
				$_SESSION = array ();
			}
		} elseif ($prefix) { // 获取session
			if (strpos ( $name, '.' )) {
				list ( $name1, $name2 ) = explode ( '.', $name );
				return isset ( $_SESSION [$prefix] [$name1] [$name2] ) ? $_SESSION [$prefix] [$name1] [$name2] : null;
			} else {
				return isset ( $_SESSION [$prefix] [$name] ) ? $_SESSION [$prefix] [$name] : null;
			}
		} else {
			if (strpos ( $name, '.' )) {
				list ( $name1, $name2 ) = explode ( '.', $name );
				return isset ( $_SESSION [$name1] [$name2] ) ? $_SESSION [$name1] [$name2] : null;
			} else {
				return isset ( $_SESSION [$name] ) ? $_SESSION [$name] : null;
			}
		}
	} elseif (is_null ( $value )) { // 删除session
		if (strpos ( $name, '.' )) {
			list ( $name1, $name2 ) = explode ( '.', $name );
			if ($prefix) {
				unset ( $_SESSION [$prefix] [$name1] [$name2] );
			} else {
				unset ( $_SESSION [$name1] [$name2] );
			}
		} else {
			if ($prefix) {
				unset ( $_SESSION [$prefix] [$name] );
			} else {
				unset ( $_SESSION [$name] );
			}
		}
	} else { // 设置session
		if ($prefix) {
			if (! isset ( $_SESSION [$prefix] )) {
				$_SESSION [$prefix] = array ();
			}
			$_SESSION [$prefix] [$name] = $value;
		} else {
			$_SESSION [$name] = $value;
		}
	}
	return null;
}

/**
 * Cookie 设置、获取、删除
 *
 * @param string $name
 *        	cookie名称
 * @param mixed $value
 *        	cookie值
 * @param mixed $option
 *        	cookie参数
 * @return mixed
 */
function cookie($name = '', $value = '', $option = null) {
	// 默认设置
	$config = array (
			'prefix' => C ( 'COOKIE_PREFIX' ), // cookie 名称前缀
			'expire' => C ( 'COOKIE_EXPIRE' ), // cookie 保存时间
			'path' => C ( 'COOKIE_PATH' ), // cookie 保存路径
			'domain' => C ( 'COOKIE_DOMAIN' ), // cookie 有效域名
			'httponly' => C ( 'COOKIE_HTTPONLY' ) 
	); // httponly设置
	   
	// 参数设置(会覆盖黙认设置)
	if (! is_null ( $option )) {
		if (is_numeric ( $option ))
			$option = array (
					'expire' => $option 
			);
		elseif (is_string ( $option ))
			parse_str ( $option, $option );
		$config = array_merge ( $config, array_change_key_case ( $option ) );
	}
	if (! empty ( $config ['httponly'] )) {
		ini_set ( "session.cookie_httponly", 1 );
	}
	// 清除指定前缀的所有cookie
	if (is_null ( $name )) {
		if (empty ( $_COOKIE ))
			return null;
		// 要删除的cookie前缀，不指定则删除config设置的指定前缀
		$prefix = empty ( $value ) ? $config ['prefix'] : $value;
		if (! empty ( $prefix )) { // 如果前缀为空字符串将不作处理直接返回
			foreach ( $_COOKIE as $key => $val ) {
				if (0 === stripos ( $key, $prefix )) {
					setcookie ( $key, '', time () - 3600, $config ['path'], $config ['domain'] );
					unset ( $_COOKIE [$key] );
				}
			}
		}
		return null;
	} elseif ('' === $name) {
		// 获取全部的cookie
		return $_COOKIE;
	}
	$name = $config ['prefix'] . str_replace ( '.', '_', $name );
	if ('' === $value) {
		if (isset ( $_COOKIE [$name] )) {
			$value = $_COOKIE [$name];
			if (0 === strpos ( $value, 'think:' )) {
				$value = substr ( $value, 6 );
				return array_map ( 'urldecode', json_decode ( MAGIC_QUOTES_GPC ? stripslashes ( $value ) : $value, true ) );
			} else {
				return $value;
			}
		} else {
			return null;
		}
	} else {
		if (is_null ( $value )) {
			setcookie ( $name, '', time () - 3600, $config ['path'], $config ['domain'] );
			unset ( $_COOKIE [$name] ); // 删除指定cookie
		} else {
			// 设置cookie
			if (is_array ( $value )) {
				$value = 'think:' . json_encode ( array_map ( 'urlencode', $value ) );
			}
			$expire = ! empty ( $config ['expire'] ) ? time () + intval ( $config ['expire'] ) : 0;
			setcookie ( $name, $value, $expire, $config ['path'], $config ['domain'] );
			$_COOKIE [$name] = $value;
		}
	}
	return null;
}

/**
 * 加载动态扩展文件
 *
 * @var string $path 文件路径
 * @return void
 */
function load_ext_file($path) {
	// 加载自定义外部文件
	if ($files = C ( 'LOAD_EXT_FILE' )) {
		$files = explode ( ',', $files );
		foreach ( $files as $file ) {
			$file = $path . 'Common/' . $file . '.php';
			if (is_file ( $file ))
				include $file;
		}
	}
	// 加载自定义的动态配置文件
	if ($configs = C ( 'LOAD_EXT_CONFIG' )) {
		if (is_string ( $configs ))
			$configs = explode ( ',', $configs );
		foreach ( $configs as $key => $config ) {
			$file = $path . 'Conf/' . $config . CONF_EXT;
			if (is_file ( $file )) {
				is_numeric ( $key ) ? C ( load_config ( $file ) ) : C ( $key, load_config ( $file ) );
			}
		}
	}
}

/**
 * 获取客户端IP地址
 *
 * @param integer $type
 *        	返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv
 *        	是否进行高级模式获取（有可能被伪装）
 * @return mixed
 */
function get_client_ip($type = 0, $adv = false) {
	$type = $type ? 1 : 0;
	static $ip = NULL;
	if ($ip !== NULL)
		return $ip [$type];
	if ($adv) {
		if (isset ( $_SERVER ['HTTP_X_FORWARDED_FOR'] )) {
			$arr = explode ( ',', $_SERVER ['HTTP_X_FORWARDED_FOR'] );
			$pos = array_search ( 'unknown', $arr );
			if (false !== $pos)
				unset ( $arr [$pos] );
			$ip = trim ( $arr [0] );
		} elseif (isset ( $_SERVER ['HTTP_CLIENT_IP'] )) {
			$ip = $_SERVER ['HTTP_CLIENT_IP'];
		} elseif (isset ( $_SERVER ['REMOTE_ADDR'] )) {
			$ip = $_SERVER ['REMOTE_ADDR'];
		}
	} elseif (isset ( $_SERVER ['REMOTE_ADDR'] )) {
		$ip = $_SERVER ['REMOTE_ADDR'];
	}
	// IP地址合法验证
	$long = sprintf ( "%u", ip2long ( $ip ) );
	$ip = $long ? array (
			$ip,
			$long 
	) : array (
			'0.0.0.0',
			0 
	);
	return $ip [$type];
}

/**
 * 发送HTTP状态
 *
 * @param integer $code
 *        	状态码
 * @return void
 */
function send_http_status($code) {
	static $_status = array (
			// Informational 1xx
			100 => 'Continue',
			101 => 'Switching Protocols',
			// Success 2xx
			200 => 'OK',
			201 => 'Created',
			202 => 'Accepted',
			203 => 'Non-Authoritative Information',
			204 => 'No Content',
			205 => 'Reset Content',
			206 => 'Partial Content',
			// Redirection 3xx
			300 => 'Multiple Choices',
			301 => 'Moved Permanently',
			302 => 'Moved Temporarily ', // 1.1
			303 => 'See Other',
			304 => 'Not Modified',
			305 => 'Use Proxy',
			// 306 is deprecated but reserved
			307 => 'Temporary Redirect',
			// Client Error 4xx
			400 => 'Bad Request',
			401 => 'Unauthorized',
			402 => 'Payment Required',
			403 => 'Forbidden',
			404 => 'Not Found',
			405 => 'Method Not Allowed',
			406 => 'Not Acceptable',
			407 => 'Proxy Authentication Required',
			408 => 'Request Timeout',
			409 => 'Conflict',
			410 => 'Gone',
			411 => 'Length Required',
			412 => 'Precondition Failed',
			413 => 'Request Entity Too Large',
			414 => 'Request-URI Too Long',
			415 => 'Unsupported Media Type',
			416 => 'Requested Range Not Satisfiable',
			417 => 'Expectation Failed',
			// Server Error 5xx
			500 => 'Internal Server Error',
			501 => 'Not Implemented',
			502 => 'Bad Gateway',
			503 => 'Service Unavailable',
			504 => 'Gateway Timeout',
			505 => 'HTTP Version Not Supported',
			509 => 'Bandwidth Limit Exceeded' 
	);
	if (isset ( $_status [$code] )) {
		header ( 'HTTP/1.1 ' . $code . ' ' . $_status [$code] );
		// 确保FastCGI模式下正常
		header ( 'Status:' . $code . ' ' . $_status [$code] );
	}
}

// 过滤表单中的表达式
function filter_exp(&$value) {
	if (in_array ( strtolower ( $value ), array (
			'exp',
			'or' 
	) )) {
		$value .= ' ';
	}
}

// 不区分大小写的in_array实现
function in_array_case($value, $array) {
	return in_array ( strtolower ( $value ), array_map ( 'strtolower', $array ) );
}